/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_TASK_INTERNAL_H
#define IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_TASK_INTERNAL_H

#include "RemoteCommunicationKit/rcp.h"
#include "decoder/imageknife_decoder_avif.h"
#include "imageknife_task.h"
#include "imageknife_request_internal.h"
#include "log.h"
#include "file_type_parser.h"
#include "queue/ijob_queue.h"
#include <future>
#include <multimedia/image_framework/image/image_source_native.h>

namespace ImageKnifePro {

class ImageKnifeTaskInternal : public ImageKnifeTask {
public:
    int traceId = 0;
    int fallbackUrlIndex = -1;

    std::string memoryKey;
    std::string fileKey;
    std::string jobKey;

    // 标记图片是否有缓存文件
    bool foundFileCache = false;
    // 用于syncLoad请求异步转同步等待
    std::shared_ptr<std::promise<std::shared_ptr<ImageKnifeTaskInternal>>> promiseSyncLoad = nullptr;

    // 用于确保取消下载时的线程安全
    std::mutex cancelMutex_;
    // 网络下载request，用于取消下载，在cancelMutex下操作
    Rcp_Request *rcpRequest = nullptr;
    // 标记网络下载是否已经被取消了, 在cancelMutex下操作
    bool rcpRequestCanceled = false;

    ImageKnifeTaskInternal(ImageRequestType type, std::shared_ptr<ImageKnifeRequestInternal> request,
        ImageSource *imageSrc) : type_(type), request_(request), imageSrc_(imageSrc), imageSrcBack_(imageSrc)
    {
        SetIsAnimator();
    }

    ImageKnifeTaskInternal(std::shared_ptr<uint8_t[]> buffer, uint32_t bufferLength, uint32_t frameIndex,
                           ImageRequestType type, std::shared_ptr<ImageKnifeRequestInternal> request);

    explicit ImageKnifeTaskInternal(std::shared_ptr<ImageKnifeTaskInternal> task);
    ImageKnifeTaskInternal(std::shared_ptr<ImageKnifeTaskInternal> task, const IJobQueue::Job &job);

    ~ImageKnifeTaskInternal() override
    {
    }

    void Detach();
    bool IsDetached();

    Interceptor *GetCurrentInterceptor() const
    {
        return interceptor_;
    }

    void SetInterceptor(Interceptor *interceptor)
    {
        interceptor_ = interceptor;
    }

    void ClearInterceptorPtr()
    {
        interceptor_ = nullptr;
    }

    bool IsSuccess() const
    {
        return success_;
    }

    void MarkSuccess()
    {
        success_ = true;
    }

    void FatalError(std::string errorInfo)
    {
        fatalError_ = true;
        EchoError("[Fatal Error] " + errorInfo);
    }

    void EchoError(std::string errorInfo) override
    {
        std::string source;
        if (interceptor_ != nullptr) {
            source = " (" + interceptor_.load()->name + ") ";
        }
        lastError_ = GetTaskInfo(type_, request_) + errorInfo + source;
        IMAGE_KNIFE_LOG(LOG_ERROR, "%{public}s", lastError_.c_str());
    }

    std::string GetLastError() const
    {
        return lastError_;
    }

    bool IsFatalErrorHappened()
    {
        return fatalError_;
    }

    static std::string GetTaskInfo(ImageRequestType type, std::shared_ptr<ImageKnifeRequestInternal> request);
    std::string GetTaskInfo() const;

    std::string GetDisplayPixelmapInfo() const;

    Image_Size GetDesiredImageSize() const override;

    OH_ImageSourceNative *GetImageSourceNative() const;

    ImageKnifeDecoderAvif *GetAvifDecoder() const;

    bool IsAnimator() const override
    {
        return isAnimator_;
    }

    bool IsAnimationImage() const
    {
        return isAnimationImage_;
    }

    ImageSource *GetImageSource() const override;

    ImageRequestType GetImageRequestType() const override;

    std::shared_ptr<ImageKnifeRequest> GetImageKnifeRequest() const override;

    std::shared_ptr<ImageKnifeRequestInternal> GetImageKnifeRequestInternal() const;

    ImageFormat GetImageBufferFormat() const override;
    void QueryImageBufferFormat();
    void SetRequestImageInfo();

    void SetFallbackUrl(std::string fallbackUrl);
    void ResetFallbackUrl();

    void MarkFileCacheNeedRename();
    bool IsFileCacheNeedRename() const;
    bool IsFrameDecodeMode() const;
    int GetDecodeFrameIndex() const override;

    void SetDecodeImageSource(std::shared_ptr<DecodeImageSource> decodeImageSource);
    std::shared_ptr<DecodeImageSource> GetDecodeImageSource() const override;
    void SetDesiredSize(Image_Size desiredSize);
    void SetFileTypeInfo(std::shared_ptr<FileTypeInfo> fileTypeInfo);
    std::shared_ptr<FileTypeInfo> GetFileTypeInfo() const override;

    void MarkDecodeFrameFinished();
    bool IsDecodeFrameFinished() const;
private:
    std::shared_ptr<ImageKnifeRequestInternal> request_ = nullptr;
    ImageRequestType type_ = ImageRequestType::MAIN_SRC;
    ImageSource *imageSrc_ = nullptr;
    ImageSource *imageSrcBack_ = nullptr;
    ImageSource fallbackUrl_;

    // 解码图片源
    std::shared_ptr<DecodeImageSource> decodeImageSource_ = nullptr;
    std::shared_ptr<FileTypeInfo> fileTypeInfo_ = nullptr;
    uint32_t frameIndex_ = 0;
    Image_Size desiredImageSize_ = {.width = 0, .height = 0};

    std::atomic<Interceptor*> interceptor_ = nullptr;
    bool success_ = false;
    bool fatalError_ = false;
    std::string lastError_;

    bool isDetached_ = false;
    bool fileCacheNeedRename_ = false;
    // 组件是否为Animator
    bool isAnimator_ = false;
    // 图片source是否为动图类型
    bool isAnimationImage_ = false;
    bool isFrameDecodeMode_ = false;
    bool isDecodeFrameFinished_ = false;
    bool isDefaultDecodeSource_ = false;
    void SetIsAnimator();
    void CheckDecodeMode();
};
} // end of namespace
#endif // IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_TASK_INTERNAL_H
